﻿using Shop.Collect;
using Shop.ExtendService;
using Shop.Model.Attr;
using Shop.Model.DB;
using Shop.Model.GoodsSku;
using Shop.Model.SpecGroup;
using Shop.RemoteModel.GoodsSku.Model;
using Shop.Service.Helper;
using Shop.Service.Interface;
using WeDonekRpc.Client;
using WeDonekRpc.Helper;
using WeDonekRpc.Model;

namespace Shop.Service.lmpl
{
    internal class GoodsSkuService : IGoodsSkuService
    {
        private readonly IGoodsSkuCollect _GoodsSku;
        private readonly ISpecGroupCollect _SpecGroup;
        private readonly IGoodsAttrCollect _GoodsAttr;
        private readonly ICategoryCollect _Category;
        private readonly IFileService _File;
        public GoodsSkuService ( IGoodsSkuCollect goodsSku,
            IFileService file,
            IGoodsAttrCollect goodsAttr,
            ICategoryCollect category,
            ISpecGroupCollect specGroup )
        {
            this._Category = category;
            this._GoodsAttr = goodsAttr;
            this._File = file;
            this._GoodsSku = goodsSku;
            this._SpecGroup = specGroup;
        }
        public GoodsSkuDto Get ( long goodsId, string specKey )
        {
            DBGoodsSku sku = this._GoodsSku.Find(goodsId, specKey);
            if ( sku == null )
            {
                return null;
            }
            GoodsSkuDto dto = sku.ConvertMap<DBGoodsSku, GoodsSkuDto>();
            dto.SkuId = sku.SkuId;
            GoodsAttrDto[] attrs = this._GoodsAttr.GetsBySkuId(sku.SkuId);
            if ( !attrs.IsNull() )
            {
                dto.Attrs = attrs.ToTree();
            }
            return dto;
        }
        public PagingResult<GoodsSkuDatum> Query ( SkuQueryParam query, IBasicPage paging )
        {
            SkuDatum[] list = this._GoodsSku.Query(query, paging, out int count);
            if ( list.IsNull() )
            {
                return new PagingResult<GoodsSkuDatum>(count);
            }
            GoodsSkuDatum[] skus = this._Format(list);
            return new PagingResult<GoodsSkuDatum>(skus, count);
        }
        private GoodsSkuDatum[] _Format ( SkuDatum[] list )
        {
            GoodsSkuDatum[] skus = list.ConvertMap<SkuDatum, GoodsSkuDatum>();
            Dictionary<long, string> category = this._Category.GetFullNames(skus.Distinct(c => c.CategoryId));
            skus.ForEach(c =>
            {
                c.CategoryName = category.GetValueOrDefault(c.CategoryId);
            });
            return skus;
        }
        public long Add ( GoodsSkuAdd data )
        {
            SpecDto[] specs = this._SpecGroup.GetSpec(data.SpecId);
            SkuAdd add = data.ConvertMap<GoodsSkuAdd, SkuAdd>();
            add.SpecsKey = data.SpecId.ToSpecKey();
            add.SkuSpec = specs.ConvertAll(c => new Model.SkuSpec.SkuSpecSet
            {
                SpecGroupId = c.GroupId,
                SpecId = c.SpecId
            });
            add.SpecsShow = specs.GetSpecsShow();
            long id = this._GoodsSku.Add(add);
            if ( !data.FileId.IsNull() )
            {
                this._File.Save(data.FileId, id);
            }
            return id;
        }
        public bool Set ( long id, GoodsSkuSet data )
        {
            DBGoodsSku sku = this._GoodsSku.Get(id);
            SkuSet set = data.ConvertMap<GoodsSkuSet, SkuSet>();
            string[] urls = sku.ImgList;
            if ( !sku.SkuImg.IsNull() )
            {
                urls = urls.Add(sku.SkuImg);
            }
            if ( !sku.ImgShow.IsNull() )
            {
                urls = urls.Add(sku.ImgShow);
            }
            if ( this._GoodsSku.Set(sku, set) )
            {
                long[] dropId = null;
                if ( !urls.IsNull() )
                {
                    dropId = urls.ConvertAll(c => long.Parse(Path.GetFileNameWithoutExtension(c)));
                }
                this._File.Sync(data.FileId, id, dropId);
                return true;
            }
            return false;
        }

        public GoodsSkuDatum[] Gets ( long[] skuId )
        {
            SkuDatum[] list = this._GoodsSku.GetSkuDatums(skuId);
            if ( list.IsNull() )
            {
                return null;
            }
            return this._Format(list);
        }
    }
}
